#!/bin/bash

# 输出打印方法
Color_Text()
{
  echo -e " \e[0;$2m$1\e[0m"
}
Echo_Blue()
{
  echo $(Color_Text "$1" "34")
}
Echo_Red()
{
  echo $(Color_Text "$1" "31")
}
Echo_Green()
{
  echo $(Color_Text "$1" "32")
}
Echo_Yellow()
{
  echo $(Color_Text "$1" "33")
}

# 查看进程数
Process_Num()
{
  # shellcheck disable=SC2046
  echo $(ps -fe |grep "$PROJ_BIN" | grep -v "grep"| wc -l)
}

# 是否启动中
Is_Staring() {
  local num=$(Process_Num)
  if [ $num -gt 0 ] && [ ! -f "$PID" ];then
    echo 1;
  else
    echo 0;
  fi
}

start() {
  # 判断服务已启动
  local processNum=$(Process_Num)
  if [ $processNum -gt 0 ];then
      Echo_Red "[ERROR] ${MICRO_MODULE_NAME} 服务已启动"
      return $!
  fi

  # 生成缓存
  Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 生成代理类和注解缓存"
  $PHP_BIN $PROJ_BIN > /dev/null 2>&1

  # 启动服务
  nohup $PHP_BIN $PROJ_BIN start >> $OUTPUT 2>&1 &
  Echo_Green "[DEBUG] ${MICRO_MODULE_NAME} 进程启动成功"
  exit $?;
}

stop() {
  # 阻塞等待进程启动完才能关闭
  while true; do
      isStaring=$(Is_Staring)
      if [ $isStaring -eq 0 ];then
        break;
      fi
  done

  # 查看进程数
  local processNum=$(Process_Num)

  if [ $processNum -eq 0 ];then
      Echo_Red "[ERROR] $MICRO_MODULE_NAME 进程已停止"
      return $!
  fi

  # 杀死主master
  kill -TERM $(cat $PID);

  # 判断是否有残留进程，通知退出
  while true; do
    sleep 1
    # 进程数
    processNum=$(Process_Num)

    # 进程关掉之后退出循环
    if [ $processNum -le 0 ]; then
      break
    fi
    # 平滑关闭进程
    pgrep -f "$PROJ_BIN" | xargs kill -TERM
  done

  Echo_Green "[DEBUG] $MICRO_MODULE_NAME 进程停止成功"
  exit $?;
}

restart()
{
  # 停止服务
  stop

  # 清除缓存
  Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 清除容器缓存"
  rm -rf "${BASE_PATH}"runtime/container

  # 生成缓存
  Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 生成代理类和注解缓存"
  $PHP_BIN $PROJ_BIN > /dev/null 2>&1;

  # 启动服务
  nohup $PHP_BIN $PROJ_BIN start >> $OUTPUT 2>&1 &
  Echo_Green "[DEBUG] ${MICRO_MODULE_NAME} 进程重启成功"
  exit $?;
}

watch()
{
  # 判断服务器是否已启动
  processNum=$(Process_Num)
  if [ $processNum -gt 0 ];then
      Echo_RED "[ERROR] ${MICRO_MODULE_NAME} 服务已启动"
      return $!
  fi

  # 生成缓存
  Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 生成代理类和注解缓存"
  $PHP_BIN $PROJ_BIN > /dev/null 2>&1;

  # 启动热更新
  nohup $PHP_BIN $PROJ_BIN server:watch >> $OUTPUT 2>&1 &
  Echo_Green "[DEBUG] ${MICRO_MODULE_NAME} 热更新进程启动成功"
  exit $?;
}

status()
{
  processNum=$(Process_Num)

  if [ $processNum -gt 0 ] && [ ! -f "$PID" ];then
    # 启动中
    Echo_Green "[DEBUG] ${MICRO_MODULE_NAME} Staring!  Worker num: ${processNum}"
  elif [ $processNum -gt 0 ] && [ -f "$PID" ];then
    # 运行中
     Echo_Green "[DEBUG] ${MICRO_MODULE_NAME} Running! Pid: $(cat $PID | awk '{print $1}') Worker num: ${processNum}"
  else
    # 关闭
     Echo_Red "[ERROR] ${MICRO_MODULE_NAME} Close!"
  fi
  exit $?;
}

clear() {
   # 清除缓存
   Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 清除容器缓存"
   rm -rf "${BASE_PATH}"runtime/container

   # 优化composer 索引
   Echo_Blue "[DEBUG] ${MICRO_MODULE_NAME} 优化 Composer 索引"
   $COMPOSER_BIN dump-autoload -o --working-dir=${BASE_PATH};
   exit $?;
}

#########################################################################
# 集群部署方式

# 需要在每台集群上修改环境变量:
#   文件位置：/etc/profile
#   文件内容: export MICRO_MODULE_NAME=api-gateway
#   文件内容: export MICRO_MODULE_NAME=order-service
#   文件内容: export MICRO_MODULE_NAME=user-service
#   文件内容: export MICRO_MODULE_NAME=task-service

# [cluster-micro-hyperf.sh]
# Desc: Hyperf微服务服务: 启动/终止/重启/热更新
# Usage: sh ./cluster-micro-hyperf.sh watch
#        sh ./cluster-micro-hyperf.sh start
#        sh ./cluster-micro-hyperf.sh stop
#        sh ./cluster-micro-hyperf.sh restart
#########################################################################

# 在服务器中配置微服模块名的环境变量
MICRO_MODULE_NAME=${MICRO_MODULE_NAME}

if [ -z "$MICRO_MODULE_NAME" ]; then
    Echo_Red "[ERROR] Environment MICRO_MODULE_NAME variable not defined"
    exit
fi

# PHP执行文件
PHP_BIN=php

# 每个微服务项目根目录
BASE_PATH=`dirname $0`"/${MICRO_MODULE_NAME}/"

# 每个微幅项目启动脚本
PROJ_BIN="${BASE_PATH}bin/hyperf.php"

# 每个微服务项目进程ID
PID="${BASE_PATH}runtime/hyperf.pid"

# composer 路径
COMPOSER_BIN=composer

# 守护进程日志
OUTPUT="${BASE_PATH}runtime/runtime/log/console.log"

# 目录不存在自动创建目录
if [ ! -f $(dirname "$OUTPUT") ];then
  mkdir -p $(dirname "$OUTPUT")
fi

case $1 in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                restart
                ;;
        watch)
                watch
                ;;
        clear)
              clear
              ;;
        status)
              status
              ;;
        *)
                echo "Usage: $0 {start|stop|restart|watch|status}";
                exit 1;
esac

